package main

import (
	"context"
	"encoding/json"
	"fmt"
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"strings"
)

var outputName string // 选中的显示设备名称

// App struct
type App struct {
	ctx context.Context
}

type Config struct {
	Brightness float64 `bson:"brightness"`
}

// NewApp creates a new App application struct
func NewApp() *App {
	return &App{}
}

// startup is called when the app starts. The context is saved
func (a *App) startup(ctx context.Context) {
	a.ctx = ctx
}

// SetBrightness 设置亮度
func (a *App) setBrightness(value float64) error {
	if value < 0.1 || value > 2.0 {
		return fmt.Errorf("亮度值超出范围 (0.1-2.0)")
	}
	cmd := exec.Command("xrandr", "--output", outputName, "--brightness", fmt.Sprintf("%f", value))
	err := cmd.Run()
	if err == nil {
		err1 := a.saveBrightness(value)
		if err1 != nil {
			return err1
		}
	}
	return err
}

// SetCustomBrightness 设置指定亮度
func (a *App) SetCustomBrightness(value float64) error {
	return a.setBrightness(value)
}

// IncreaseBrightness 增加亮度
func (a *App) IncreaseBrightness(step float64) error {
	// 获取当前亮度
	currentBrightness, err := a.GetCurrentBrightness()
	if err != nil {
		return err
	}

	// 增加亮度
	newBrightness := currentBrightness + step
	if newBrightness > 2.0 {
		newBrightness = 2.0
	}

	return a.setBrightness(newBrightness)
}

// DecreaseBrightness 减少亮度
func (a *App) DecreaseBrightness(step float64) error {
	// 获取当前亮度
	currentBrightness, err := a.GetCurrentBrightness()
	if err != nil {
		return err
	}

	// 减少亮度
	newBrightness := currentBrightness - step
	if newBrightness < 0.1 {
		newBrightness = 0.1
	}

	return a.setBrightness(newBrightness)
}

// InitializeBrightness 初始化亮度
func (a *App) InitializeBrightness() (float64, error) {

	var currentBrightness float64

	currentBrightness, err := a.loadBrightness()
	// 未找到配置文件
	if err != nil {
		currentBrightness, err = a.GetCurrentBrightness()
		if err != nil {
			return 1.0, err
		}
	}

	return currentBrightness, nil
}

// GetCurrentBrightness 获取当前屏幕显示亮度
func (a *App) GetCurrentBrightness() (float64, error) {
	var currentBrightness float64
	var connectedDisplayDevice int32
	var selectIndex int32

	cmd := exec.Command("xrandr", "--verbose")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return 0.0, err
	}
	// 选取已激活的显示设备
	for _, line := range strings.Split(string(output), "\n") {
		selectIndex += 1
		if strings.Contains(line, outputName) && strings.Contains(line, "connected") {
			connectedDisplayDevice = selectIndex
			continue
		}
		if strings.Contains(line, "Brightness:") {
			if selectIndex > connectedDisplayDevice {
				parts := strings.Split(line, "Brightness:")
				if len(parts) > 1 {
					_, _ = fmt.Sscanf(parts[1], " %f", &currentBrightness)
					break
				}
			}
		}
	}

	return currentBrightness, err
}

// GetAvailableOutputs 获取所有可用的显示设备
func (a *App) GetAvailableOutputs() ([]string, error) {
	cmd := exec.Command("xrandr")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return nil, err
	}
	var displays []string
	lines := strings.Split(string(output), "\n")
	for _, line := range lines {
		if strings.Contains(line, " connected") {
			parts := strings.Split(line, " ")
			if len(parts) > 0 {
				displays = append(displays, parts[0])
			}
		}
	}

	return displays, nil
}

// SetSelectedOutput 设置选中的显示设备
func (a *App) SetSelectedOutput(name string) {
	outputName = name
}

func (a *App) shutdown(ctx context.Context) {}

// saveBrightness 保存屏幕亮度配置文件
func (a *App) saveBrightness(brightness float64) error {
	currentUser, err := user.Current()
	if err != nil {
		return err
	}
	// 拼接配置文件路径名称
	configPath := filepath.Join(currentUser.HomeDir, ".config", "brightness.setting")

	config := Config{Brightness: brightness}

	file, err := os.Create(configPath)
	if err != nil {
		return err
	}
	defer func(file *os.File) {
		_ = file.Close()
	}(file)

	return json.NewEncoder(file).Encode(config)
}

// loadBrightness 加载屏幕配置亮度
func (a *App) loadBrightness() (float64, error) {
	currentUser, err := user.Current()
	if err != nil {
		return 1.0, err
	}
	configPath := filepath.Join(currentUser.HomeDir, ".config", "brightness.setting")
	file, err := os.Open(configPath)
	if err != nil {
		// 如果文件不存在, 返回默认值1.0
		if os.IsNotExist(err) {
			return 1.0, err
		}
		return 1.0, err
	}
	defer func(file *os.File) {
		_ = file.Close()
	}(file)

	// 返回保存的配置值
	var config Config
	if err := json.NewDecoder(file).Decode(&config); err != nil {
		return 1.0, err
	}

	return config.Brightness, err
}
